package com.amt.util;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Title: HisServiceUtil.java
 * @Package com.amt.util
 * @Description: TODO(远程调用HisService)
 * @author 刘云升
 * @date 2019年6月17日 下午5:20:33 Copyright (c) ©1994-2019 Scjydz.com All Rights
 *       Reserved.
 */
@Component
@ConfigurationProperties(prefix = "hisservice")
@Slf4j
@Data
public class HisServiceUtil {

	// 远程调用url地址
	private String address; // "http://192.168.0.40:8900/HIS.asmx/";
	
	//检查结果明细
	private String addressone; // "http://192.168.0.32:8280/services/MP_PACS_SELECT_V_PACS_PT?wsdl";
	//检验结果明细
	private String addresstwo; // "http://192.168.0.32:8280/services/MP_LIS_SELECT_V_PT_LAB_RESULT?wsdl";
	//查询检查项目:
	private String addressthree; // "http://192.168.0.32:8280/services/MP_HIS_SELECT_V_PT_EXAM_MASTER?wsdl";
	//查询检验项目
	private String addressfour; // "http://192.168.0.32:8280/services/MP_LIS_SELECT_V_PT_LIS_INSPECTION_SAMPLE?wsdl";
	//查询停诊医生列表
	private String addressfive; // http://220.167.62.133:9016/services/MP_HIS_SELECT_V_PT_CLINIC_STOP?wsdl
	//查询检验检查项目new
	private String addresssix;

	// http://192.168.101.136:8000/HIS.asmx/
	// http://171.221.217.33:6080/HIS.asmx/
	// http://182.150.23.41:6080/HIS.asmx/
	/**
	 * @description: HttpURLConnection远程执行POST方法调用外部接口
	 * @param address     外部url地址
	 * @param RequestCode 业务代码
	 * @param xml         传参格式为<id>1</id><name>张三</name>
	 * @return 接口调用XML字符串
	 * @throws Exception io异常
	 */
	public String requestWSDL(String method, String xml) throws Exception {

		OutputStreamWriter oStream = null;
		BufferedReader reader = null;
		StringBuffer sbf = new StringBuffer();

		URL url = new URL(address);
		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		con.setRequestMethod("POST");
		//con.setRequestProperty("Accept-Encoding", "gzip,deflate");
		con.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setConnectTimeout(300000);
		con.setReadTimeout(300000);
		oStream = new OutputStreamWriter(con.getOutputStream());
		oStream.write(xml);
		oStream.flush();
		oStream.close();
		reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
			sbf.append(line);
		}
		reader.close();
		oStream.close();
		con.disconnect();

		if (oStream != null) {
			oStream.close();
		}
		if (reader != null) {
			reader.close();
		}
		return sbf.toString();
	}


	public String requestApplet(String method, String xml) throws Exception {

		log.info("请求方法{}=====请求内容{}",method,xml);

		OutputStreamWriter oStream = null;
		BufferedReader reader = null;
		StringBuffer sbf = new StringBuffer();

		//URL url = new URL("http://172.30.4.243:8311/insurance/applet/"+method);
		URL url = new URL("http://172.16.255.122:8311/insurance/applet/"+method);

		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		con.setRequestMethod("POST");
		con.setRequestProperty("Content-Type", "text/plain;charset=UTF-8");
		con.setRequestProperty("accessToken", "555666");
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setConnectTimeout(300000);
		con.setReadTimeout(300000);
		oStream = new OutputStreamWriter(con.getOutputStream());
		oStream.write(xml);
		oStream.flush();
		oStream.close();
		reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
			sbf.append(line);
		}
		reader.close();
		oStream.close();
		con.disconnect();

		if (oStream != null) {
			oStream.close();
		}
		if (reader != null) {
			reader.close();
		}
		log.info("请求方法{}========返回内容{}",method,sbf);
		return sbf.toString();
	}

	/**
	 * @description: HttpURLConnection远程执行POST方法调用外部接口
	 * @param num         1、检查结果明细2、检验结果明细3、查询检查项目4、查询检验项目
	 * @param xml         传参格式为<id>1</id><name>张三</name>
	 * @param action		Action地址
	 * @return 接口调用XML字符串
	 * @throws Exception io异常
	 */
	public String requestWSDLString(int num ,String xml,String action) throws Exception {
		System.out.println(xml);
		OutputStreamWriter oStream = null;
		BufferedReader reader = null;
		StringBuffer sbf = new StringBuffer();
		URL url = null;
		switch (num) {
		case 1:
			url = new URL(addressone);
			break;
		case 2:
			url = new URL(addresstwo);
			break;
		case 3:
			url = new URL(addressthree);
			break;
		case 4:
			url = new URL(addressfour);
			break;
		case 5:
			url = new URL(addressfive);
			break;
		default:
			break;
		}
		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
		con.setRequestProperty("SOAPAction", action);
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setConnectTimeout(300000);
		con.setReadTimeout(300000);
//		con.setConnectTimeout(4000);
//		con.setReadTimeout(10000);
		oStream = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
		oStream.write(xml);
		oStream.flush();
		oStream.close();
		reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
		String line;
		while ((line = reader.readLine()) != null) {
			sbf.append(line);
		}
		reader.close();
		oStream.close();
		con.disconnect();

		if (oStream != null) {
			oStream.close();
		}
		if (reader != null) {
			reader.close();
		}
		return sbf.toString();
	}

	public  Map<String, Object> xmlparse(String xml) throws DocumentException {
		String xmls = StringEscapeUtils.unescapeXml(xml);
		Document doc = DocumentHelper.parseText(xmls);
		Element root = doc.getRootElement();
		Element body = root.element("Response");
		String resultCode = body.element("ResultCode").getText();
		String errorMsg = body.element("ErrorMsg").getText();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("resultCode", resultCode);
		map.put("response", body);
		map.put("errorMsg",errorMsg);
		return map;
	}

	/**
	 * 
	 * @description: 获取XML入参
	 * @param xml     参数内容
	 * @param pMethod 方法名
	 * @return
	 */
	public  String getXML(String xml, String pMethod) {
		StringBuffer requestXML = new StringBuffer();
		requestXML.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
		requestXML.append(
				"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n");
		requestXML.append("<soap:Body>");
		requestXML.append("<" + pMethod + " xmlns=\"http://www.cnsesan.com\">\r\n");
		if (StringUtil.isNotEmpty(xml)) {
			requestXML.append(xml);
		}
		requestXML.append("</" + pMethod + ">");
		requestXML.append("</soap:Body>");
		requestXML.append("</soap:Envelope>");
		return requestXML.toString();
	}
	
	/**
	 * 
	 * @description:  元素节点封装
	 * @param xml     XML文件
	 * @return        Map集合
	 * @throws DocumentException
	 */
	public  Map<String, Object> xmlparseTwo(String xml) throws DocumentException{
		Map<String, Object> map = new HashMap<String, Object>();
		String xmls = StringEscapeUtils.unescapeXml(xml);
		Document doc = DocumentHelper.parseText(xmls);
		Element returns = doc.getRootElement().element("Body").element("response").element("return");
		Element entities = returns.element("ENTITIES");
		map.put("RESPONSE_CODE", entities.element("RESPONSE_STATUS").attributeValue("RESPONSE_CODE"));
		map.put("ENTITIES", entities.elements("ENTITY"));
		return map;
	}


	/**
	 * 单个element转map
	 * @param element
	 * @return
	 */
	public Map<String,Object> elementToMap(Element element,Map<String,Object> map){
		if (element.isTextOnly()) {
			map.put(element.getName(), element.getText());
			return map;
		}

		@SuppressWarnings("unchecked")
		Iterator<Element> eItor = element.elementIterator();
		while (eItor.hasNext()) {
			elementToMap(eItor.next(), map);
		}
		return map;
	}



	public void offAppoint(String queueNo,String shiftName,String doctorRowid,String subscribeDate,String cardId){
		StringBuilder xmlParam = new StringBuilder();
		xmlParam.append("<Request>");
		xmlParam.append("<RegistFlag></RegistFlag>");
		xmlParam.append("<QueueNo>").append(queueNo).append("</QueueNo>");
		xmlParam.append("<ShiftName>").append(shiftName).append("</ShiftName>");
		xmlParam.append("<RowId>").append(doctorRowid).append("</RowId>");
		xmlParam.append("<DoctID></DoctID>");
		xmlParam.append("<RegisterDate>").append(subscribeDate).append("</RegisterDate>");
		xmlParam.append("<UserId>").append(SystemConstantUtil.USERID).append("</UserId>");
		xmlParam.append("<CardNo>").append(cardId).append("</CardNo>");
		xmlParam.append("</Request>");
		try {
			log.info("取消占号请求参数：{}",xmlParam.toString());
			String str = requestWSDL("OffAppoint", "xmlpara=" + xmlParam.toString());
			log.info("取消占号结果：{}",str);
		} catch (Exception e) {
			log.error("调用his取消预约接口异常：{}",e);
		}
	}


	public String confirmAppNoTime(String cardId,String doctorRowid,String subscribeDate,String shiftName,String queueNo){
		StringBuilder xmlParam = new StringBuilder();
		xmlParam.append("<Request>");
		xmlParam.append("<CardNo>").append(cardId).append("</CardNo>");
		xmlParam.append("<RowId>").append(doctorRowid).append("</RowId>");
		xmlParam.append("<RegisterDate>").append(subscribeDate)
				.append("</RegisterDate>");
		xmlParam.append("<ShiftName>").append(shiftName).append("</ShiftName>");
		xmlParam.append("<QueueNo>").append(queueNo).append("</QueueNo>");
		xmlParam.append("<Amount>").append(SystemConstantUtil.ZERO).append("</Amount>");
		xmlParam.append("<Bank>").append(SystemConstantUtil.BANK).append("</Bank>");
		xmlParam.append("<BankNo>").append(SystemConstantUtil.ZERO).append("</BankNo>");
		xmlParam.append("<payway>").append(SystemConstantUtil.ZERO).append("</payway>");
		xmlParam.append("<merchantid>").append(SystemConstantUtil.ZERO).append("</merchantid>");
		xmlParam.append("<TranctionId>").append(SystemConstantUtil.ZERO).append("</TranctionId>");
		xmlParam.append("<UserId>").append(SystemConstantUtil.USERID).append("</UserId>");
		xmlParam.append("<CinicTimePrompt></CinicTimePrompt>");
		xmlParam.append("<IsTimePoint>").append(0).append("</IsTimePoint>");
		xmlParam.append("</Request>");
		try {
			log.info("调用hisConfirmAppNoTime接口参数：{}",xmlParam.toString());
			return requestWSDL("ConfirmAppNoTime", "xmlpara=" + xmlParam.toString());
		} catch (Exception e) {
			log.error("调用his取消预约接口异常：{}",e);
			return null;
		}
	}


	public void returnClinicNo(String queueNo,String shiftName,String doctoerRowid,String subscribeDate,String cardId,String cardName,String serno,String id){
		StringBuilder xmlParam = new StringBuilder();
		xmlParam.append("<Request>");
		xmlParam.append("<RegistFlag></RegistFlag>");
		xmlParam.append("<QueueNo>").append(queueNo).append("</QueueNo>");
		xmlParam.append("<ShiftName>").append(shiftName).append("</ShiftName>");
		xmlParam.append("<RowId>").append(doctoerRowid).append("</RowId>");
		xmlParam.append("<RegisterDate>").append(subscribeDate)
				.append("</RegisterDate>");
		xmlParam.append("<UserId>").append(SystemConstantUtil.USERID).append("</UserId>");
		xmlParam.append("<CardNo>").append(cardId).append("</CardNo>");
		xmlParam.append("<Name>").append(cardName).append("</Name>");
		xmlParam.append("<Serno>").append(serno).append("</Serno>");
		xmlParam.append("<PayPlatformSN>").append("yygh").append(id).append("</PayPlatformSN>");
		xmlParam.append("<Bank>").append(SystemConstantUtil.BANK).append("</Bank>");
		xmlParam.append("<payway>").append(SystemConstantUtil.PAYWAY).append("</payway>");
		xmlParam.append("</Request>");
		try {
			log.info("调用ReturnClinicNo接口参数：{}",xmlParam.toString());
			String str = requestWSDL("ReturnClinicNo", "xmlpara=" + xmlParam.toString());
			log.info("调用ReturnClinicNo结果：{}",str);
		} catch (Exception e) {
			log.error("调用his退号接口异常：{}",e);

		}
	}

}
